package com.adk.backend.service.impl;

import com.adk.backend.entity.LxFinanceCheckDetails;
import com.adk.backend.mapper.CostMapper;
import com.adk.backend.mapper.FinanceCheckDetailsMapper;
import com.adk.backend.service.CostService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 成本管理服务实现类
 */
@Slf4j
@Service
public class CostServiceImpl implements CostService {
    
    @Autowired
    private CostMapper costMapper;
    
    @Autowired
    private FinanceCheckDetailsMapper financeCheckDetailsMapper;
    
    
    @Override
    public List<Map<String, Object>> getCouCostList(Map<String, Object> params) {
        return costMapper.selectCouCostList(params);
    }
    
    @Override
    public List<Map<String, Object>> getCargoCostList(Map<String, Object> params) {
        return costMapper.selectCargoCostList(params);
    }
    
    @Override
    public List<Map<String, Object>> getSeaCostList(Map<String, Object> params) {
        return costMapper.selectSeaCostList(params);
    }
    
    @Override
    public List<Map<String, Object>> getFinanceCheckMonthList() {
        return costMapper.selectFinanceCheckMonthList();
    }
    
    @Override
    public Map<String, Object> getFinanceCheckDetailsByBlId(Long blId) {
        return costMapper.selectFinanceCheckDetailsById(blId);
    }
    
    @Override
    public Map<String, Object> calculateTotalAmount(List<Long> blIds) {
        return costMapper.calculateTotalAmount(blIds);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setBlFinanceCheckMonth(Long blId, Long monthId, Long oldMonthId) {
        try {
            costMapper.updateBlFinanceCheck(blId, monthId);
            // 更新新月份的财务对账汇总
            if (monthId != null && monthId > 0) {
                updateFinanceCheckTotal(monthId);
            }
            // 更新旧月份的财务对账汇总
            if (oldMonthId != null && oldMonthId > 0) {
                updateFinanceCheckTotal(oldMonthId);
            }
            return true;
        } catch (Exception e) {
            log.error("设置提单财务对账月份失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateFinanceCheckTotal(Long monthId) {
        try {
            if (monthId == null || monthId == 0) {
                return false;
            }
            costMapper.updateFinanceCheckTotal(monthId);
            return true;
        } catch (Exception e) {
            log.error("更新财务对账汇总失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveZgFee(LxFinanceCheckDetails details) {
        try {
            // 计算总中港费用: totalZg = (zgWeigth * zgFee) + zgZfFee
            if (details.getZgWeigth() != null && details.getZgFee() != null) {
                BigDecimal totalZg = details.getZgWeigth().multiply(details.getZgFee());
                if (details.getZgZfFee() != null) {
                    totalZg = totalZg.add(details.getZgZfFee());
                }
                details.setTotalZg(totalZg);
            }
            
            if (details.getId() != null && details.getId() > 0) {
                // 更新
                financeCheckDetailsMapper.updateById(details);
            } else {
                // 新增
                financeCheckDetailsMapper.insert(details);
            }
            // 更新财务对账汇总
            updateFinanceCheckTotalByBlId(details.getBlId());
            return true;
        } catch (Exception e) {
            log.error("保存中港费用失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveTxFee(LxFinanceCheckDetails details) {
        try {
            // 计算总头程费用: totalTx = (txWeigth * txFee) + txZfFee + bgFee
            if (details.getTxWeigth() != null && details.getTxFee() != null) {
                BigDecimal totalTx = details.getTxWeigth().multiply(details.getTxFee());
                if (details.getTxZfFee() != null) {
                    totalTx = totalTx.add(details.getTxZfFee());
                }
                if (details.getBgFee() != null) {
                    totalTx = totalTx.add(details.getBgFee());
                }
                details.setTotalTx(totalTx);
            }
            
            if (details.getId() != null && details.getId() > 0) {
                financeCheckDetailsMapper.updateById(details);
            } else {
                financeCheckDetailsMapper.insert(details);
            }
            // 更新财务对账汇总
            updateFinanceCheckTotalByBlId(details.getBlId());
            return true;
        } catch (Exception e) {
            log.error("保存头程费用失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveDeclareFee(LxFinanceCheckDetails details) {
        try {
            // 根据qghId查询qghType判断类型：qghType=2为DB类型，其他为非DB类型
            // DB类型: totalCustom = customWeight * customFee * exchangeRate
            // 非DB类型: totalCustom = customFee + slaFee + customZfFee + vatFee + customHdFee + psFee + qtFee
            Integer qghType = null;
            if (details.getQghId() != null && details.getQghId() > 0) {
                Map<String, Object> qghInfo = costMapper.selectQghInfo(details.getQghId());
                if (qghInfo != null && qghInfo.get("qghType") != null) {
                    qghType = (Integer) qghInfo.get("qghType");
                }
            }
            
            if (qghType != null && qghType == 2) {
                // DB类型
                BigDecimal customWeight = details.getCustomWeight() != null ? details.getCustomWeight() : BigDecimal.ZERO;
                BigDecimal customFee = details.getCustomFee() != null ? details.getCustomFee() : BigDecimal.ZERO;
                BigDecimal exchangeRate = details.getExchangeRate() != null ? details.getExchangeRate() : BigDecimal.ONE;
                BigDecimal totalCustom = customWeight.multiply(customFee).multiply(exchangeRate);
                details.setTotalCustom(totalCustom);
            } else {
                // 非DB类型
                BigDecimal totalCustom = BigDecimal.ZERO;
                if (details.getCustomFee() != null) totalCustom = totalCustom.add(details.getCustomFee());
                if (details.getSlaFee() != null) totalCustom = totalCustom.add(details.getSlaFee());
                if (details.getCustomZfFee() != null) totalCustom = totalCustom.add(details.getCustomZfFee());
                if (details.getVatFee() != null) totalCustom = totalCustom.add(details.getVatFee());
                if (details.getCustomHdFee() != null) totalCustom = totalCustom.add(details.getCustomHdFee());
                if (details.getPsFee() != null) totalCustom = totalCustom.add(details.getPsFee());
                if (details.getQtFee() != null) totalCustom = totalCustom.add(details.getQtFee());
                details.setTotalCustom(totalCustom);
            }
            
            if (details.getId() != null && details.getId() > 0) {
                financeCheckDetailsMapper.updateById(details);
            } else {
                financeCheckDetailsMapper.insert(details);
            }
            // 更新财务对账汇总
            updateFinanceCheckTotalByBlId(details.getBlId());
            return true;
        } catch (Exception e) {
            log.error("保存报关费用失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveCertFee(LxFinanceCheckDetails details) {
        try {
            // 如果shipType=3，根据courQty和courPer计算totalCour
            // 否则直接使用totalCour
            if (details.getShipType() != null && details.getShipType() == 3 
                    && details.getCourQty() != null && details.getCourPer() != null) {
                BigDecimal totalCour = BigDecimal.valueOf(details.getCourQty()).multiply(details.getCourPer());
                details.setTotalCour(totalCour);
            }
            
            if (details.getId() != null && details.getId() > 0) {
                financeCheckDetailsMapper.updateById(details);
            } else {
                financeCheckDetailsMapper.insert(details);
            }
            // 更新财务对账汇总
            updateFinanceCheckTotalByBlId(details.getBlId());
            return true;
        } catch (Exception e) {
            log.error("保存证书费用失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean savePsFee(LxFinanceCheckDetails details) {
        try {
            // 计算派送费用: newPsFee = (totalCtnsPsL * newPsFeeL) + (totalCtnsPsW * newPsFeeW)
            if (details.getTotalCtnsPsL() != null && details.getNewPsFeeL() != null 
                    && details.getTotalCtnsPsW() != null && details.getNewPsFeeW() != null) {
                BigDecimal newPsFee = BigDecimal.valueOf(details.getTotalCtnsPsL())
                        .multiply(details.getNewPsFeeL())
                        .add(BigDecimal.valueOf(details.getTotalCtnsPsW()).multiply(details.getNewPsFeeW()));
                details.setNewPsFee(newPsFee);
            }
            
            if (details.getId() != null && details.getId() > 0) {
                financeCheckDetailsMapper.updateById(details);
            } else {
                financeCheckDetailsMapper.insert(details);
            }
            // 更新财务对账汇总
            updateFinanceCheckTotalByBlId(details.getBlId());
            return true;
        } catch (Exception e) {
            log.error("保存派送费用失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveExchangeRate(Long blId, Long fcdId, BigDecimal newRate) {
        try {
            LxFinanceCheckDetails details;
            if (fcdId != null && fcdId > 0) {
                details = financeCheckDetailsMapper.selectById(fcdId);
                if (details == null) {
                    details = new LxFinanceCheckDetails();
                    details.setBlId(blId);
                }
            } else {
                QueryWrapper<LxFinanceCheckDetails> wrapper = new QueryWrapper<>();
                wrapper.eq("bl_id", blId);
                details = financeCheckDetailsMapper.selectOne(wrapper);
                if (details == null) {
                    details = new LxFinanceCheckDetails();
                    details.setBlId(blId);
                }
            }
            details.setNewRate(newRate);
            if (details.getId() != null && details.getId() > 0) {
                financeCheckDetailsMapper.updateById(details);
            } else {
                financeCheckDetailsMapper.insert(details);
            }
            // 更新财务对账汇总
            updateFinanceCheckTotalByBlId(blId);
            return true;
        } catch (Exception e) {
            log.error("保存汇率失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveHllFee(Long blId, Long fcdId, BigDecimal hllFee) {
        try {
            LxFinanceCheckDetails details;
            if (fcdId != null && fcdId > 0) {
                details = financeCheckDetailsMapper.selectById(fcdId);
                if (details == null) {
                    details = new LxFinanceCheckDetails();
                    details.setBlId(blId);
                }
            } else {
                QueryWrapper<LxFinanceCheckDetails> wrapper = new QueryWrapper<>();
                wrapper.eq("bl_id", blId);
                details = financeCheckDetailsMapper.selectOne(wrapper);
                if (details == null) {
                    details = new LxFinanceCheckDetails();
                    details.setBlId(blId);
                }
            }
            details.setHllFee(hllFee);
            if (details.getId() != null && details.getId() > 0) {
                financeCheckDetailsMapper.updateById(details);
            } else {
                financeCheckDetailsMapper.insert(details);
            }
            // 更新财务对账汇总
            updateFinanceCheckTotalByBlId(blId);
            return true;
        } catch (Exception e) {
            log.error("保存货拉拉费用失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveVatFee(LxFinanceCheckDetails details) {
        try {
            if (details.getId() != null && details.getId() > 0) {
                financeCheckDetailsMapper.updateById(details);
            } else {
                financeCheckDetailsMapper.insert(details);
            }
            // 更新财务对账汇总
            updateFinanceCheckTotalByBlId(details.getBlId());
            return true;
        } catch (Exception e) {
            log.error("保存VAT费用失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveGsFee(Long blId, Long fcdId, BigDecimal gsFee) {
        try {
            LxFinanceCheckDetails details;
            if (fcdId != null && fcdId > 0) {
                details = financeCheckDetailsMapper.selectById(fcdId);
            } else {
                QueryWrapper<LxFinanceCheckDetails> wrapper = new QueryWrapper<>();
                wrapper.eq("bl_id", blId);
                details = financeCheckDetailsMapper.selectOne(wrapper);
            }
            if (details == null) {
                details = new LxFinanceCheckDetails();
                details.setBlId(blId);
            }
            details.setGsFee(gsFee);
            if (details.getId() != null && details.getId() > 0) {
                financeCheckDetailsMapper.updateById(details);
            } else {
                financeCheckDetailsMapper.insert(details);
            }
            // 更新财务对账汇总
            updateFinanceCheckTotalByBlId(blId);
            return true;
        } catch (Exception e) {
            log.error("保存GS费用失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveDdFee(Long blId, Long fcdId, BigDecimal ddFee) {
        try {
            LxFinanceCheckDetails details;
            if (fcdId != null && fcdId > 0) {
                details = financeCheckDetailsMapper.selectById(fcdId);
            } else {
                QueryWrapper<LxFinanceCheckDetails> wrapper = new QueryWrapper<>();
                wrapper.eq("bl_id", blId);
                details = financeCheckDetailsMapper.selectOne(wrapper);
            }
            if (details == null) {
                details = new LxFinanceCheckDetails();
                details.setBlId(blId);
            }
            details.setDdFee(ddFee);
            if (details.getId() != null && details.getId() > 0) {
                financeCheckDetailsMapper.updateById(details);
            } else {
                financeCheckDetailsMapper.insert(details);
            }
            // 更新财务对账汇总
            updateFinanceCheckTotalByBlId(blId);
            return true;
        } catch (Exception e) {
            log.error("保存DD费用失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveQtFee(Long blId, Long fcdId, BigDecimal qtFee) {
        try {
            LxFinanceCheckDetails details;
            if (fcdId != null && fcdId > 0) {
                details = financeCheckDetailsMapper.selectById(fcdId);
            } else {
                QueryWrapper<LxFinanceCheckDetails> wrapper = new QueryWrapper<>();
                wrapper.eq("bl_id", blId);
                details = financeCheckDetailsMapper.selectOne(wrapper);
            }
            if (details == null) {
                details = new LxFinanceCheckDetails();
                details.setBlId(blId);
            }
            details.setQtFee(qtFee);
            if (details.getId() != null && details.getId() > 0) {
                financeCheckDetailsMapper.updateById(details);
            } else {
                financeCheckDetailsMapper.insert(details);
            }
            // 更新财务对账汇总
            updateFinanceCheckTotalByBlId(blId);
            return true;
        } catch (Exception e) {
            log.error("保存QT费用失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveCargoPsFee(Long blId, Long fcdId, BigDecimal newPsFee) {
        try {
            LxFinanceCheckDetails details;
            if (fcdId != null && fcdId > 0) {
                details = financeCheckDetailsMapper.selectById(fcdId);
            } else {
                QueryWrapper<LxFinanceCheckDetails> wrapper = new QueryWrapper<>();
                wrapper.eq("bl_id", blId);
                details = financeCheckDetailsMapper.selectOne(wrapper);
            }
            if (details == null) {
                details = new LxFinanceCheckDetails();
                details.setBlId(blId);
            }
            details.setNewPsFee(newPsFee);
            if (details.getId() != null && details.getId() > 0) {
                financeCheckDetailsMapper.updateById(details);
            } else {
                financeCheckDetailsMapper.insert(details);
            }
            // 更新财务对账汇总
            updateFinanceCheckTotalByBlId(blId);
            return true;
        } catch (Exception e) {
            log.error("保存Cargo派送费用失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveCneeFee(Long blId, Long fcdId, BigDecimal cnee) {
        try {
            LxFinanceCheckDetails details;
            if (fcdId != null && fcdId > 0) {
                details = financeCheckDetailsMapper.selectById(fcdId);
            } else {
                QueryWrapper<LxFinanceCheckDetails> wrapper = new QueryWrapper<>();
                wrapper.eq("bl_id", blId);
                details = financeCheckDetailsMapper.selectOne(wrapper);
            }
            if (details == null) {
                details = new LxFinanceCheckDetails();
                details.setBlId(blId);
            }
            details.setCnee(cnee);
            if (details.getId() != null && details.getId() > 0) {
                financeCheckDetailsMapper.updateById(details);
            } else {
                financeCheckDetailsMapper.insert(details);
            }
            // 更新财务对账汇总
            updateFinanceCheckTotalByBlId(blId);
            return true;
        } catch (Exception e) {
            log.error("保存收货人费用失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveCargoDeclareFee(LxFinanceCheckDetails details) {
        try {
            // 计算总清关费用: customFee + jcFee
            if (details.getCustomFee() == null) details.setCustomFee(BigDecimal.ZERO);
            if (details.getJcFee() == null) details.setJcFee(BigDecimal.ZERO);
            BigDecimal totalCustom = details.getCustomFee().add(details.getJcFee());
            details.setTotalCustom(totalCustom);
            
            if (details.getId() != null && details.getId() > 0) {
                financeCheckDetailsMapper.updateById(details);
            } else {
                financeCheckDetailsMapper.insert(details);
            }
            // 更新财务对账汇总
            updateFinanceCheckTotalByBlId(details.getBlId());
            return true;
        } catch (Exception e) {
            log.error("保存Cargo报关费用失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateFinanceCheckExchangeRate(Long monthId, BigDecimal exchangeRate) {
        try {
            // TODO: 更新财务对账表的汇率，并更新所有关联的明细
            return true;
        } catch (Exception e) {
            log.error("更新财务对账月份汇率失败", e);
            return false;
        }
    }
    
    @Override
    public Map<String, Object> getQghInfo(Long qghId) {
        return costMapper.selectQghInfo(qghId);
    }
    
    @Override
    public List<Map<String, Object>> getQghList() {
        return costMapper.selectQghList();
    }
    
    @Override
    public List<Map<String, Object>> getPsFeeOrderList(String blNo) {
        return costMapper.selectPsFeeOrderList(blNo);
    }
    
    /**
     * 根据提单ID更新财务对账汇总
     */
    private void updateFinanceCheckTotalByBlId(Long blId) {
        try {
            if (blId == null || blId == 0) {
                return;
            }
            Map<String, Object> blInfo = costMapper.selectBlFinanceCheck(blId);
            if (blInfo != null && blInfo.get("f_check") != null) {
                Long monthId = ((Number) blInfo.get("f_check")).longValue();
                if (monthId > 0) {
                    updateFinanceCheckTotal(monthId);
                }
            }
        } catch (Exception e) {
            log.error("根据提单ID更新财务对账汇总失败", e);
        }
    }
}

